import logging
from datetime import datetime, timedelta

# 休：正常工作日(周一至周五)放假日期
from flask import current_app

holidays_exception = [
    # '20220101',  # 元旦,周三
    # '20200122',  # 如：公司提前放假
    # '20200123',  # 如：公司提前放假
    # '20200124',  # 除夕,周五
    # '20200127',  # 春节,周一
    # '20200128',  # 春节
    # '20200129',  # 春节
    # '20200130',  # 春节,周四
    # '20200131',  # 新冠疫情国务院放假
    # '20200201',  # 新冠疫情国务院放假
    '20220404',  # 清明,周一
    '20220405',  # 清明,周二
    '20220502',  # 劳动节,周一
    '20220503',  # 劳动节,周二
    '20220504',  # 劳动节,周三
    '20220603',  # 端午,周五
    '20220912',  # 中秋,周一
    '20221003',  # 国庆,周一
    '20221004',  # 国庆,周二
    '20221005',  # 国庆,周三
    '20221006',  # 国庆,周四
    '20221007',  # 国庆,周五
]

logger = logging.getLogger(__name__)


# 班：正常周末(周六和周五)上班日期
# workdays_exception = [
#     '20200201',  # 春节, 周六
#     '20200426',  # 劳动节, 周日
#     '20200509',  # 劳动节, 周六
#     '20200628',  # 端午, 周日
#     '20200927',  # 国庆,周六
#     '20201010',  # 国庆,周六
# ]

class HolidayUtil:

    @staticmethod
    def is_tradingDay(day):
        """
            Args:
                day: 日期, 默认为今日
            Returns:
                True: 上班
                False: 放假
        """
        week_day = datetime.isoweekday(day)  # 今天星期几(星期一 = 1，周日 = 7)
        is_work_day_in_week = week_day in range(1, 6)  # 这周是不是非周末，正常工作日, 不考虑调假
        day_str = f'{day.year}{str(day.month).zfill(2)}{str(day.day).zfill(2)}'

        if day_str in holidays_exception:
            return False
        elif is_work_day_in_week:
            return True
        return False

    @staticmethod
    def is_TradingTime(day):
        """
        判断是否是可统计的交易日
            Args:
                day: 日期, 默认为今日

            Returns:
                True: 上班
                False: 放假
        """

        week_day = datetime.weekday(day) + 1  # 今天星期几(星期一 = 1，周日 = 7)
        is_work_day_in_week = week_day in range(1, 6)  # 这周是不是非周末，正常工作日, 不考虑调假
        day_str = f'{day.year}{str(day.month).zfill(2)}{str(day.day).zfill(2)}'

        if day_str in holidays_exception:
            return False
        elif is_work_day_in_week:
            d_time = datetime.strptime(str(day.date()) + '15:00', '%Y-%m-%d%H:%M')
            if day > d_time:
                return True
        return False


    # 获取前1天或N天的日期，beforeOfDay=1：前1天；beforeOfDay=N：前N天
    @staticmethod
    def getdate(date, beforeOfDay=1):
        # 计算偏移量
        offset = timedelta(days=-beforeOfDay)
        # 获取想要的日期的时间
        return date + offset

    @staticmethod
    def get_date_str(beforeOfDay):
        today = datetime.now()
        # 计算偏移量
        offset = timedelta(days=-beforeOfDay)
        # 获取想要的日期的时间
        re_date = (today + offset).strftime('%Y-%m-%d')
        return re_date


    # 获取前一周的所有日期(weeks=1)，获取前N周的所有日期(weeks=N)
    @staticmethod
    def getBeforeWeekDays(weeks=1):
        # 0,1,2,3,4,5,6,分别对应周一到周日
        week = datetime.now().weekday()
        days_list = []
        start = 7 * weeks + week
        end = week
        for index in range(start, end, -1):
            day = HolidayUtil.get_date_str(index)
            days_list.append(day)
        current_app.logger.info("{}".format(days_list))

    @staticmethod
    def getBeforeTradingDays(weeks=1):
        '''
        获取前几周股票交易日期
        :param weeks:
        :return:
        '''
        # 0,1,2,3,4,5,6,分别对应周一到周日
        days_list = []
        tradingDays = 5 * weeks
        end = 0
        while True:
            if len(days_list) >= tradingDays:
                break
            if end == 0:
                if HolidayUtil.is_TradingTime(HolidayUtil.getdate(date=datetime.now(),beforeOfDay=end)):
                    day = HolidayUtil.get_date_str(end)
                    days_list.append(day)
            elif HolidayUtil.is_tradingDay(HolidayUtil.getdate(date=datetime.now(),beforeOfDay=end)):
                day = HolidayUtil.get_date_str(end)
                days_list.append(day)
            end += 1

        return days_list

    @staticmethod
    def getLastTradingDay(day):
        '''
        获取最新交易日
        :param day:
        :return:
        '''
        while True:
            logger.info("获取最近交易日:day={}".format(day))
            if HolidayUtil.is_TradingTime(day):
                break
            day = datetime.strptime(str(HolidayUtil.getdate(date=day, beforeOfDay=1).date()) + '16:00', '%Y-%m-%d%H:%M')
        return day.date()


if __name__ == '__main__':
    # print(getdate(1))

    print(HolidayUtil.getLastTradingDay(datetime.now()))
